import 'dart:async';

import 'package:kq_flutter_core_widget/websocket/kq_web_socket_state.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/status.dart' as status;

/// 外部使用步骤
/// 1.setConfig() 相关配置
/// 2.connect() 建立socket连接
/// 3.onListener() 监听消息
/// 4.sendHeartPacket(心跳数据) 发送心跳包
/// 5.销毁
class KqWebSocket {
  static KqWebSocketState state = KqWebSocketState();
  static Timer? heartTimer;

  /// 相关配置
  /// socketUrl 链接地址
  /// heartPacket 心跳包数据
  /// heartClinetTime 心跳包维持发送时间
  static void setConfig(String socketUrl, dynamic heartPacket,
      {int? heartClinetTime}) {
    state.socketUrl = socketUrl;
    state.heartPacket = heartPacket;
    if (heartClinetTime != null) {
      state.heartClinetTime = heartClinetTime;
    }
  }

  /// 连接webSocket 服务器
  static Future connect() async {
    await pause();
    await initSocketChannel();
  }

  static Future initSocketChannel() async {
    if (state.socketUrl != null &&
        state.socketStatus == SocketStatus.unconnect) {
      /// 连接
      state.socketChannel = IOWebSocketChannel.connect(state.socketUrl!);
      state.socketStatus = SocketStatus.connecting;

      /// 创建心跳包
      initHeaderPacket();
    }
  }

  static void initHeaderPacket() {
    if ((state.socketStatus == SocketStatus.connecting ||
            state.socketStatus == SocketStatus.connected) &&
        heartTimer == null) {
      /// 已经在建立链接，定时器还未创建
      heartTimer = Timer.periodic(Duration(seconds: state.heartClinetTime),
          (timer) async {
        if (state.socketChannel != null) {
          /// 发送心跳数据
          sendHeartPacket();
        }
      });
    }
  }

  /// 监听socket消息
  static void onListener(
      {required Function(dynamic data) socketCallback,
      required Function() onSocketDone,
      required Function(dynamic error) onSocketError}) {
    state.socketChannel?.stream.listen((event) {
      state.socketStatus = SocketStatus.connected;
      if (event == state.heartPacket) {
        /// 心跳包，不处理
      } else {
        socketCallback(event);
      }
      state.reconnectNum = 0;
      state.isCloseChannel = false;
    }, onDone: () {
      /// 通道关闭
      state.socketStatus = SocketStatus.unconnect;

      if (state.socketChannel != null) {
        state.reconnectNum++;
        if (state.reconnectNum < 5 && !state.isCloseChannel) {
          ///自动重连
          reconnectSocket();
        } else {
          onSocketDone();
        }
      }
    }, onError: (e) {
      /// 通道发生错误
      state.socketStatus = SocketStatus.unconnect;
      if (state.socketChannel != null) {
        state.reconnectNum++;

        if (state.reconnectNum < 5 && !state.isCloseChannel) {
          ///自动重连
          reconnectSocket();
        } else {
          onSocketError(e);
        }
      }
    });
  }

  /// 发送数据
  static void sendMsg(dynamic data) {
    state.socketChannel?.sink.add(data);
  }

  /// 发送心跳包
  static void sendHeartPacket() {
    state.socketChannel?.sink.add(state.heartPacket);
    state.heartStatus = true;
  }

  /// 销毁心跳包
  static void deleteHeartPacket() {
    if (state.heartStatus) {
      heartTimer?.cancel();
      state.heartStatus = false;
    }
  }

  /// 重新连接socket
  static void reconnectSocket() {
    /// 先销毁心跳，再建立连接
    deleteHeartPacket();
    connect();
  }

  /// 关闭通道，退出时一定要关闭，避免资源占用
  static Future close() async {
    if (state.socketChannel != null) {
      state.isCloseChannel = true;
      state.reconnectNum = 0;
      state.socketChannel?.sink.close();
      deleteHeartPacket();
      state.socketChannel = null;
      state.socketStatus = SocketStatus.unconnect;
    }
  }

  /// 暂停
  static Future pause() async {
    if (state.socketChannel != null) {
      state.isCloseChannel = true;
      state.reconnectNum = 0;
      state.socketChannel?.sink.close();
      deleteHeartPacket();
      state.socketStatus = SocketStatus.unconnect;
    }
  }
}
